#pragma once

#include <linux/pfn.h>
#include <linux/types.h>

#ifndef CONFIG_PAGE_SHIFT
#define CONFIG_PAGE_SHIFT 12
#endif

#include <vdso/page.h>

/*
 * Use struct definitions to apply C type checking
 */

/* Page Global Directory entry */
typedef struct
{
    unsigned long pgd;
} pgd_t;

/* Page Table entry */
typedef struct
{
    unsigned long pte;
} pte_t;

/* Page Middle Directory entry */
typedef struct
{
    unsigned long pmd;
} pmd_t;

/* Page 4th Directory entry */
typedef struct
{
    unsigned long p4d;
} p4d_t;

/* Page Upper Directory entry */
typedef struct
{
    unsigned long pud;
} pud_t;

typedef unsigned long pgprot_t;

typedef struct page *pgtable_t;


#define pte_val(x)	((x).pte)
#define pgd_val(x)	((x).pgd)
#define pgprot_val(x)	((x))

#define __pgprot(x)	(x)

#define __pgd(x)	((pgd_t) { (x) })
#define __pte(x)	((pte_t) { (x) })

uintptr_t __virt_to_phys(uintptr_t x);
uintptr_t linear_mapping_pa_to_va(uintptr_t x);

#define __pa(x) (phys_addr_t)(x)
#define __va(x) (void*)(x)

#define ARCH_PFN_OFFSET (PFN_DOWN(0x81c00000)) //todo just test

#define phys_to_pfn(phys)	(PFN_DOWN(phys))
#define pfn_to_phys(pfn)	(PFN_PHYS(pfn))

#define virt_to_pfn(vaddr)	(phys_to_pfn(__pa(vaddr)))

#define virt_to_page(vaddr)	(pfn_to_page(virt_to_pfn(vaddr)))

#include <asm-generic/memory_model.h>
